package kamikaze.service;

import java.io.Serializable;

import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import kamikaze.bean.Admin;
import kamikaze.bean.User;
import kamikaze.utils.Database;
import kamikaze.utils.Database.Template;

import com.google.appengine.api.datastore.Key;

public class UserSession implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 3800488799620217300L;

	public enum Type {
		User, Admin
	}

	private Key key;
	private Type type;

	public UserSession(Key key, Type type) {
		this.key = key;
		this.type = type;
	}

	private UserSession() {

	}

	public boolean isValid() {
		return key != null;
	}

	public static UserSession getFrom(HttpServletRequest request) {
		HttpSession session = request.getSession();

		if (session == null) {
			return new UserSession();
		}

		UserSession result = (UserSession) session.getAttribute("UserSession");

		if (result == null) {
			return new UserSession();
		} else {
			return result;
		}
	}

	public static void setTo(HttpServletRequest request, UserSession userSession) {
		request.getSession(true).setAttribute("UserSession", userSession);
	}

	public Type getType() {
		return type;
	}

	public Key getKey() {
		return key;
	}

	public Admin asAdmin() {

		if (!isValid()) {
			throw new BusinessException("you must login first");
		} else if (type != Type.Admin) {
			throw new BusinessException("you must login as admin");
		}

		return Database.get().execute(new Template<Admin>() {
			@Override
			public Admin query(EntityManager em) throws Exception {
				return em.find(Admin.class, key);
			}
		});
	}

	public User asUser() {

		if (!isValid()) {
			throw new BusinessException("you must login first");
		} else if (type != Type.User) {
			throw new BusinessException("you must login as admin");
		}

		return Database.get().execute(new Template<User>() {
			@Override
			public User query(EntityManager em) throws Exception {
				return em.find(User.class, key);
			}
		});
	}

}
